#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include"dlink.h"


static void  __insert(node_t *p, node_t *n, node_t *cur);
static node_t * __find_cur(const list_t *mylist, const void *key, cmp_t cmp);


int list_init(list_t **mylist, int size){
	*mylist = malloc(sizeof(list_t));
	if(*mylist == NULL){
		return -1;
	}
	(*mylist)->size = size;
	(*mylist)->head.pre = &(*mylist)->head;
	(*mylist)->head.next = &(*mylist)->head;

	return 0;
}

void *__creat_node(const void *data, int size){
	node_t *node = malloc(sizeof(node_t) + size);
	if(node == NULL)
		return NULL;
	memcpy(node->data, data, size);
	node->pre = node->next = node;

	return node;
}

static void  __insert(node_t *p, node_t *n, node_t *cur){
	cur->next = n;
	cur->pre = p;

	n->pre = cur;
	p->next = cur;
}

int list_insert(list_t *mylist, const void *data){
	node_t * node = __creat_node(data, mylist->size);
	if(node == NULL)
		return -1;
	__insert(&mylist->head, mylist->head.next, node);
	
	return 0;
}

int list_insert_tail(list_t *mylist, const void *data){
	node_t * node = __creat_node(data, mylist->size);
	if(node == NULL)
		return -1;
	__insert(mylist->head.pre, &mylist->head, node);
	
	return 0;

}

int list_is_empty(const list_t *mylist){
	return mylist->head.pre == &mylist->head && mylist->head.next == &mylist->head;
}

static node_t * __find_cur(const list_t *mylist, const void *key, cmp_t cmp){
	node_t *cur = NULL;
	for(cur = mylist->head.next; cur != &mylist->head; cur = cur->next){
		if(!cmp(cur->data, key)){
			return cur;
		}
	}
	return NULL;
}
void *list_search(const list_t *mylist, const void *key, cmp_t cmp){
	node_t *node = __find_cur(mylist, key, cmp);
	if(NULL == node)
		return NULL;
	return node->data;
}

static void __del(node_t **d){
	node_t *del = *d;

	del->next->pre = del->pre;
	del->pre->next = del->next;

	del->next = NULL;
	del->pre  = NULL;

	free(*d);
	*d = NULL;
}

int list_delete(list_t *mylist, const void *key, cmp_t cmp){
	node_t *node = __find_cur(mylist, key, cmp);
	if(node == NULL)
		return -1;
	__del(&node);

	return 0;

}

 
int list_update(const list_t *mylist, const void *key, const void *data, cmp_t cmp){
	node_t *node = __find_cur(mylist, key, cmp);
	if(NULL == node)
		return -1;
	memcpy(node->data, data, mylist->size);

	return 0;
}


void list_display(const list_t *mylist, pri_t pri){
	node_t *node = mylist->head.next;

	for(; node->next != &mylist->head; node = node->next){
		pri(node->data);
	}
}

static int __always__cmp(const void *data1, const void *data2){
	return 0;
}


void list_destroy(list_t **mylist){
	if(*mylist == NULL){
		return;
	}
	node_t *node = (*mylist)->head.next;
	for(int i = 1; node != &(*mylist)->head; i++){
		list_delete(*mylist, NULL, __always__cmp);
		node = (*mylist)->head.next;
		printf("坤坤%d灌篮\n", i);
	}
	
	/*while(!list_is_empty(*mylist)){		
		list_delete(*mylist, NULL, __always__cmp);
	}
	*/
	free(*mylist);
	*mylist = NULL;
}


